#ifndef CLOGGER_H_
#define CLOGGER_H_

#include <fstream>
#include <ostream>
#include <sstream>
#include <vector>
#include "../../exception/cfilenotexistexception.h"

using namespace std;

struct TMessage {
  unsigned int depth;
  int prior;
  string text;
};

/**
 * CLogger - class for application logging
 * @author Marek Rost
 * @date 26.03.2008
 */
class CLogger : public CObject {
public:
  CLogger(int priorMin = PRIORITY_ERROR, bool keepMemory = false,
      unsigned int maxLocalMemory = MEMORY_MAX_1MB);
  CLogger(ostream &out, int priorMin = PRIORITY_ERROR,
      bool keepMemory = false, unsigned int maxLocalMemory = MEMORY_MAX_1MB);
  CLogger(string path, int priorMin = PRIORITY_ERROR,
      bool keepMemory = false, unsigned int maxLocalMemory = MEMORY_MAX_1MB);
  ~CLogger();
  void addMsg(string str, int priority = PRIORITY_ERROR);
  void addDbg(string str);
  void addInf(string str);
  void addWrn(string str);
  void addErr(string str);
  void addCrt(string str);
  void beginSubLvl();
  void endSubLvl();
  void clearLog();
  void saveMemoryToFile(string path, int type = MEMORY_FILE_TYPE_PLAIN);
  void saveMemoryToStream(ostream &out);
  static string getClassName() {
    return "CLogger";
  }
  static string OUTPUT_INDENT;
  static const int MEMORY_FILE_TYPE_PLAIN = 10;
  static const int MEMORY_FILE_TYPE_HTML = 20;
  static const int PRIORITY_DEBUG = -1;
  static const int PRIORITY_INFO = 0;
  static const int PRIORITY_WARNING = 1;
  static const int PRIORITY_ERROR = 2;
  static const int PRIORITY_CRITICAL = 3;
  static const unsigned int MEMORY_MAX_2MB = 2097152;
  static const unsigned int MEMORY_MAX_1MB = 1048576;
  static const unsigned int MEMORY_MAX_512KB = 524288;
  static const unsigned int MEMORY_MAX_256KB = 262144;
  static const unsigned int MEMORY_MAX_128KB = 131072;
private:
  string printMsg(vector<TMessage>::iterator it);
  string printPriorSign(int prior);
  bool toFile, toMemory, toStream;
  unsigned int logDepth, memoryMax, memoryUsed;
  int priorPrint;
  ofstream file, stream;
  vector<TMessage> memory;
};

#endif
